home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
psi110g.zip
/
MAILUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-05
|
7KB
|
261 lines
/* General Mail Utilities
* culled from other files to reduce unnecessary cross references.
* This material is believed to be in the public domain.
*/
#ifdef MSDOS
#include <io.h>
#endif
#include <fcntl.h>
#include <ctype.h>
#include "global.h"
#include "socket.h"
#include "mailutil.h"
#include "mailbox.h"
#include "smtp.h"
#include "files.h"
#include "bm.h"
#include "index.h"
#ifdef linux
extern int close __ARGS((int)); /* this should be in fcntl.h... */
extern int unlink __ARGS((char *)); /* can't include unistd.h, collisions */
#endif
/* Jan 92 Bill Simpson
* The following routines were combined from smtpserv.c,
* pop3cli.c and nntpcli.c
*/
/* June 93 - Johan. K. Reinalda, WG7J
* Mail file indexing added.
*/
#ifdef POP3CLIENT
/* Receive message from socket, copying to file.
* Returns number of lines received, -1 indicates error
*/
int
recvmail(s,buf,len,fp,trace)
int s; /* Socket index */
char *buf; /* Line buffer */
unsigned len; /* Length of buffer */
FILE *fp; /* File to copy into */
int trace; /* to trace or not to trace */
{
int lines = 0;
while (recvline(s,buf,len) != -1) {
register char *p = buf;
if (trace >= 4)
log(s,"<==%s", buf);
/* check for end of message . or escaped .. */
if (*p == '.') {
if (*++p == '\n') {
if (trace >= 3)
log(s,"received %d lines", lines);
return lines;
} else if ( *p != '.' ) {
p--;
}
} else if (strncmp(p,"From ",5) == 0) {
/* for UNIX mail compatiblity */
(void) putc('>',fp);
}
/* Append to data file */
fputs(p,fp);
++lines;
}
if ( trace >= 1 )
log(s,"receive error after %d lines", lines);
return -1;
}
#endif
#if (defined(POP2CLIENT) || defined(POP3CLIENT))
/* Copy from the work file into the mailbox.
* -1 indicates error
*/
int
copymail(filename,buf,len,wfp,trace)
char *filename; /* Target Filename */
char *buf; /* Line buffer */
unsigned len; /* Length of buffer */
FILE *wfp; /* File to copy from */
int trace; /* to trace or not to trace */
{
FILE *mfp = NULLFILE;
while (mlock(Mailspool,filename)) {
pause(10000L); /* 10 seconds */
}
sprintf(buf,"%s/%s.txt",Mailspool,filename);
if ((mfp = fopen(buf,"a+")) == NULL) {
if ( trace >= 1 )
log(-1,"*** Unable to open %s!!!\n", buf);
tprintf("\n*** Unable to open %s!!!\n", buf);
rmlock(Mailspool,filename);
return -1;
}
rewind(wfp); /* start of new mail, just to be safe ! */
fseek(mfp,0,SEEK_END); /* End of mailbox file */
/* loop for all lines in file */
while(fgets(buf,len,wfp) != NULL) {
pwait(NULL); /* give other processes time in long copy */
fputs(buf,mfp); /* Write to the mailbox */
}
fclose(mfp);
/* Update the index */
IndexFile(filename,0);
rmlock(Mailspool,filename);
return 0;
}
#endif
/* Jan 92 Bill Simpson
* The following routines were extracted from smtpserv.c
* and smtpcli.c, since they are used from several places.
*/
static void mklockname(char *lockname,char *dir,char *id) {
if (id == NULLCHAR || !*id) strcpy(lockname, dir);
else sprintf(lockname,"%s/%s",dir,id);
dirformat(lockname);
strcat(lockname,".lck");
}
/* create mail lockfile */
int
mlock(dir,id)
char *dir,*id;
{
int fd;
char lockname[FILE_PATH_SIZE];
/* Try to create the lock file in an atomic operation */
mklockname(lockname,dir,id);
#ifdef AMIGA
/* don't ask, really, just don't ask... I'd do file locking on
* an Amiga much more differently than this.
*/
if(access(lockname, 0) == 0)
return -1;
#endif
if((fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT,0600)) == -1)
return -1;
close(fd);
return 0;
}
/* remove mail lockfile */
int
rmlock(dir,id)
char *dir,*id;
{
char lockname[FILE_PATH_SIZE];
mklockname(lockname,dir,id);
return(unlink(lockname));
}
/* Jan 92 Bill Simpson
* The following routines were extracted from mailbox.c,
* since they are used from several places.
*/
/* Read the rewrite file for lines where the first word is a regular
* expression and the second word are rewriting rules. The special
* character '$' followed by a digit denotes the string that matched
* a '*' character. The '*' characters are numbered from 1 to 9.
* Example: the line "*@*.* $2@$1.ampr.org" would rewrite the address
* "foo@bar.xxx" to "bar@foo.ampr.org".
* $H is replaced by our hostname, and $$ is an escaped $ character.
* If the third word on the line has an 'r' character in it, the function
* will recurse with the new address.
*/
char *
rewrite_address(addr)
char *addr;
{
char *argv[10], buf[PLINELEN], *cp, *cp2, *retstr;
int cnt;
FILE *fp;
if ((fp = fopen(Rewritefile,READ_TEXT)) == NULLFILE)
return NULLCHAR;
memset((char *)argv,0,10*sizeof(char *));
while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
if(*buf == '#') /* skip commented lines */
continue;
if((cp = strchr(buf,' ')) == NULLCHAR) /* get the first word */
if((cp = strchr(buf,'\t')) == NULLCHAR)
continue;
*cp = '\0';
if((cp2 = strchr(buf,'\t')) != NULLCHAR){
*cp = ' ';
cp = cp2;
*cp = '\0';
}
if(!wildmat(addr,buf,argv))
continue; /* no match */
rip(++cp);
/* scan past additional whitespaces */
while (*cp == ' ' || *cp == '\t') ++cp;
cp2 = retstr = (char *) callocw(1,PLINELEN);
while(*cp != '\0' && *cp != ' ' && *cp != '\t')
if(*cp == '$') {
if(isdigit(*(++cp)))
if(argv[*cp - '0'-1] != '\0')
strcat(cp2,argv[*cp - '0'-1]);
if(*cp == 'h' || *cp == 'H') /* Our hostname */
strcat(cp2,Hostname);
if(*cp == '$') /* Escaped $ character */
strcat(cp2,"$");
cp2 = retstr + strlen(retstr);
cp++;
}
else
*cp2++ = *cp++;
for(cnt=0; argv[cnt] != NULLCHAR; ++cnt)
free(argv[cnt]);
fclose(fp);
/* If there remains an 'r' character on the line, repeat
* everything by recursing.
*/
if(strchr(cp,'r') != NULLCHAR || strchr(cp,'R') != NULLCHAR) {
if((cp2 = rewrite_address(retstr)) != NULLCHAR) {
free(retstr);
return cp2;
}
}
return retstr;
}
fclose(fp);
return NULLCHAR;
}
int dorewrite(int argc, char *argv[], void *p) {
char *address = rewrite_address(argv[1]);
tprintf("to: %s\n", address ? address : argv[1]);
if(address)
free(address);
return 0;
}